﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.System;
using HengTong.ViewModel._Admin.SysUserJobPositionVms;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Hr.SysHrTransferRequestBillVms;

public partial class SysHrTransferRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "调岗调薪")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "调岗调薪")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成", "将流程状态设置为已完成", "调岗调薪")]
    public async Task Complete(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    /// <summary>
    /// 调岗调薪流程结束后，更新用户岗位信息和员工档案
    /// </summary>
    [WorkflowOperation("更新岗位", "调岗调薪流程结束后更新用户岗位信息和员工档案", "调岗调薪")]
    public async Task UpdateUserJobPosition(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        if (Entity == null || Entity.ID == Guid.Empty)
        {
            MSD.AddModelError(" ", "调岗调薪单据不存在");
            return;
        }

        var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrTransferRequestBillVm>>();

        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(10)
            },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            logger.LogInformation("开始处理调岗调薪岗位更新，单据ID: {EntityId}, 员工ID: {PersonId}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, Entity.PersonId, currentUser, DateTime.Now);

            // 更新单据状态
            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            // 查询目标用户信息
            var targetUser = await DC.Set<FrameworkUser>()
                .AsNoTracking()
                .FirstOrDefaultAsync(u => u.PersonId == Entity.PersonId);

            if (targetUser == null)
            {
                logger.LogWarning("未找到员工ID为 {PersonId} 的用户信息，单据ID: {EntityId}", Entity.PersonId, Entity.ID);
                throw new Exception($"未找到员工ID为 {Entity.PersonId} 的用户信息");
            }

            logger.LogInformation("找到目标用户，工号: {StaffNo}, 姓名: {UserName}", targetUser.ITCode, targetUser.Name);

            // 更新员工档案信息
            var sysPerson = await DC.Set<SysPerson>()
                .FirstOrDefaultAsync(p => p.ID == Entity.PersonId);

            if (sysPerson != null)
            {
                bool personUpdated = false;

                // 更新部门信息
                if (Entity.NewGroupId != null && sysPerson.GroupId != Entity.NewGroupId)
                {
                    logger.LogInformation("更新员工档案部门，员工ID: {PersonId}, 原部门ID: {OriginalGroupId}, 新部门ID: {NewGroupId}",
                        Entity.PersonId, sysPerson.GroupId, Entity.NewGroupId);

                    sysPerson.GroupId = Entity.NewGroupId;
                    DC.UpdateProperty(sysPerson, x => x.GroupId);
                    personUpdated = true;
                }

                // 更新岗位信息
                if (Entity.NewPositionId != null && sysPerson.JobPositionId != Entity.NewPositionId)
                {
                    logger.LogInformation(
                        "更新员工档案岗位，员工ID: {PersonId}, 原岗位ID: {OriginalPositionId}, 新岗位ID: {NewPositionId}",
                        Entity.PersonId, sysPerson.JobPositionId, Entity.NewPositionId);

                    sysPerson.JobPositionId = Entity.NewPositionId;
                    DC.UpdateProperty(sysPerson, x => x.JobPositionId);
                    personUpdated = true;
                }

                // 更新员工档案的修改信息
                if (personUpdated)
                {
                    sysPerson.UpdateTime = DateTime.Now;
                    sysPerson.UpdateBy = currentUser;
                    DC.UpdateProperty(sysPerson, x => x.UpdateTime);
                    DC.UpdateProperty(sysPerson, x => x.UpdateBy);

                    await DC.SaveChangesAsync();
                    logger.LogInformation("员工档案更新完成，员工ID: {PersonId}", Entity.PersonId);
                }
                else
                {
                    logger.LogInformation("员工档案无需更新，员工ID: {PersonId}", Entity.PersonId);
                }
            }
            else
            {
                logger.LogWarning("未找到员工档案信息，员工ID: {PersonId}", Entity.PersonId);
            }

            // 检查是否有新岗位需要设置
            if (Entity.NewPositionId != null)
            {
                logger.LogInformation("开始更新用户岗位关系，工号: {StaffNo}, 原岗位ID: {OriginalPositionId}, 新岗位ID: {NewPositionId}",
                    targetUser.ITCode, Entity.OriginalPositionId, Entity.NewPositionId);

                // 删除原有岗位信息（如果存在原岗位）
                if (Entity.OriginalPositionId != null)
                {
                    var deletedCount = await DC.Set<SysUserJobPosition>()
                        .Where(e => e.UserId == targetUser.ID && e.JobPositionId == Entity.OriginalPositionId)
                        .ExecuteDeleteAsync();

                    logger.LogInformation(
                        "删除原有用户岗位关系，工号: {StaffNo}, 原岗位ID: {OriginalPositionId}, 删除记录数: {DeletedCount}",
                        targetUser.ITCode, Entity.OriginalPositionId, deletedCount);
                }

                // 检查新岗位是否已存在，避免重复添加
                var existingJobPosition = await DC.Set<SysUserJobPosition>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(e => e.UserId == targetUser.ID && e.JobPositionId == Entity.NewPositionId);

                if (existingJobPosition == null)
                {
                    // 添加新的岗位信息
                    var newJobPosition = new SysUserJobPosition
                    {
                        UserId = targetUser.ID,
                        JobPositionId = Entity.NewPositionId.Value
                    };

                    await DC.Set<SysUserJobPosition>().AddAsync(newJobPosition);
                    logger.LogInformation("添加新用户岗位关系，工号: {StaffNo}, 新岗位ID: {NewPositionId}",
                        targetUser.ITCode, Entity.NewPositionId);

                    // 保存岗位变更
                    await DC.SaveChangesAsync();

                    // 更新用户部门组关系
                    var jobPositionVm = new SysUserJobPositionVm
                    {
                        DC = this.DC,
                        Wtm = this.Wtm
                    };
                    await jobPositionVm.UpdateUserGroupAsync(targetUser.ID);

                    logger.LogInformation("更新用户部门组关系完成，工号: {StaffNo}", targetUser.ITCode);

                    // 清除用户缓存
                    //await Wtm.RemoveUserCache(targetUser.ITCode);
                    logger.LogInformation("清除用户缓存完成，工号: {StaffNo}", targetUser.ITCode);
                }
                else
                {
                    logger.LogInformation("新用户岗位关系已存在，跳过添加，工号: {StaffNo}, 岗位ID: {JobPositionId}",
                        targetUser.ITCode, Entity.NewPositionId);
                }
            }
            else
            {
                logger.LogInformation("未设置新岗位，仅删除原有岗位，单据ID: {EntityId}, 工号: {StaffNo}", Entity.ID, targetUser.ITCode);

                // 如果只需要删除原岗位而不添加新岗位
                if (Entity.OriginalPositionId != null)
                {
                    var deletedCount = await DC.Set<SysUserJobPosition>()
                        .Where(e => e.UserId == targetUser.ID && e.JobPositionId == Entity.OriginalPositionId)
                        .ExecuteDeleteAsync();

                    logger.LogInformation(
                        "仅删除原有用户岗位关系，工号: {StaffNo}, 原岗位ID: {OriginalPositionId}, 删除记录数: {DeletedCount}",
                        targetUser.ITCode, Entity.OriginalPositionId, deletedCount);
                }
            }

            await DC.SaveChangesAsync();

            transactionScope.Complete();

            logger.LogInformation("成功处理调岗调薪更新，员工ID: {PersonId}, 工号: {StaffNo}, 流程状态: {WorkflowStatus}",
                Entity.PersonId, targetUser.ITCode, Entity.WorkflowStatus);
        }
        catch (Exception e)
        {
            logger.LogError(e, "处理调岗调薪更新失败，单据ID: {EntityId}, 员工ID: {PersonId}, 操作人: {CurrentUser}, 时间: {Time}",
                Entity.ID, Entity.PersonId, currentUser, DateTime.Now);

            MSD.AddModelError(" ", $"处理调岗调薪更新失败: {e.Message}");
        }
    }
}